﻿/*
Commerce by Onex – eCommerce software platform (www.ecommerce.byonex.com)
Copyright (C) 2008-2010 by Onex Group

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 */
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data;
using System.Text;

using ShopModel;


namespace ShopDAO
{
    public class PropertyDAO
    {
        private string connectionString;

        public PropertyDAO()
        {
            connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["csShop"].ConnectionString;
        }

        /// <summary>
        /// Pobiera wszystkie właściwości w określonym języku, łącznie z możliwymi wartościami dla typów słownikowych.
        /// (Downloads all properties in a given language including possible values for dictionaries types.)
        /// </summary>
        /// <param name="LanguageID">
        /// ID języka lub wartość 'NULL'.
        /// (Language ID or 'null' value.)
        /// </param>
        /// <returns>
        /// Zwraca listę obiektów ProductPropertyDetail zawierającą opisy właściwości produktu łącznie z możliwymi wartościami dla typów słownikowych.
        /// (Returns list of ProductPropertyDetail objects containing descriptions of product’s properties together with possible values for dictionaries types.)
        /// </returns>
        public List<ProductPropertyDetail> GetAllProperties(int? LanguageID)
        {
            ProductPropertyDetail property;
            List<ProductPropertyDetail> result = new List<ProductPropertyDetail>();
            SqlConnection connection = new SqlConnection(connectionString);
            SqlCommand command = connection.CreateCommand();
            SqlDataReader reader;

            command.CommandText = "GetAllProperties";
            command.CommandType = CommandType.StoredProcedure;

            command.Parameters.Add(new SqlParameter("@LanguageID", LanguageID));

            try
            {
                connection.Open();
                reader = command.ExecuteReader(CommandBehavior.CloseConnection);

                while (reader.Read())
                {
                    property = new ProductPropertyDetail();

                    property.Id = (int)reader["IDproperty"];
                    property.TypeOfProperty = (PropertyType)reader["PropertyType"];
                    property.Name = reader["Name"].ToString();
                    property.Description = reader["Description"].ToString();
                    property.IsSearchCriterion = (bool)reader["IsSearchCriterion"];

                    if (property.TypeOfProperty == PropertyType.Dictionary || property.TypeOfProperty == PropertyType.MultiDictionary)
                    {
                        property.ValuesList = GetDictionaryValue(property.Id, LanguageID);
                    }

                    result.Add(property);
                }

                return result;
            }
            catch (Exception ex)
            {
                ErrorLogger.LogError(ex);
                return null;
            }
            finally
            {
                connection.Close();
            }
        }

        /// <summary>
        /// Pobiera informacje o właściwościach wybranego produktu, w określonym języku łącznie z możliwymi wartościami dla typów słownikowych.
        /// (Downloads information about properties of chosen product in a defined language with possible values for dictionaries types.)
        /// </summary>
        /// <param name="PropertyID">
        /// Unikalne ID właściwości.
        /// (Unique property ID.)
        /// </param>
        /// <param name="LanguageID">
        /// Unikalne ID języka lub wartość 'NULL'.
        /// (Unique language ID or 'null' value.)
        /// </param>
        /// <returns>
        /// Zwraca obiekt ProductPropertyDetail zawierający informacje właściwościach produktu w określonym języku, łącznie z możliwymi wartościami dla typów słownikowych.
        /// (Returns ProductPropertyDetail object contining information about product’s properties in a defined language, including possible values for dictionaries types.)
        /// </returns>
        public ProductPropertyDetail PropertyById(int PropertyID, int? LanguageID)
        {
            ProductPropertyDetail property = null;
            SqlConnection connection = new SqlConnection(connectionString);
            SqlCommand command = connection.CreateCommand();
            SqlDataReader reader;

            command.CommandText = "PropertyById";
            command.CommandType = CommandType.StoredProcedure;

            command.Parameters.Add(new SqlParameter("@PropertyID", PropertyID));
            command.Parameters.Add(new SqlParameter("@LanguageID", LanguageID));

            try
            {
                connection.Open();
                reader = command.ExecuteReader(CommandBehavior.CloseConnection);
                if (reader.Read())
                {
                    property = new ProductPropertyDetail();
                    property.Id = (int)reader["IDproperty"];
                    property.TypeOfProperty = (PropertyType)reader["PropertyType"];
                    property.Name = reader["Name"].ToString();
                    property.Description = reader["Description"].ToString();
                    property.IsSearchCriterion = (bool)reader["IsSearchCriterion"];

                    if (property.TypeOfProperty == PropertyType.Dictionary || property.TypeOfProperty == PropertyType.MultiDictionary)
                    {
                        property.ValuesList = GetDictionaryValue(property.Id, LanguageID);
                    }
                }

                reader.Close();
                return property;
            }
            catch (Exception ex)
            {
                ErrorLogger.LogError(ex);
                return null;
            }
            finally
            {
                connection.Close();
            }
        }

        /// <summary>
        /// Pobiera informacje o wybranej waściwości w wybranym języku.
        /// (Downloads information about chosen property in a chosen language. )
        /// </summary>
        /// <param name="PropertyID">
        /// Unikalne ID właściwości.
        /// (Unique property ID.)
        /// </param>
        /// <param name="LanguageID">
        /// Unikalne ID języka lub wartość 'NULL'.
        /// (Unique language ID or 'null' value.)
        /// </param>
        /// <returns>
        /// Zwraca listę obiektów DictionaryValue opisujących wartości słownika.
        /// (Returns list of DictionaryValue objects describing dictionary values.)
        /// </returns>
        private List<DictionaryValue> GetDictionaryValue(int PropertyID, int? LanguageID)
        {
            List<DictionaryValue> result = new List<DictionaryValue>();
            SqlConnection connection = new SqlConnection(connectionString);
            SqlDataReader reader;
            DictionaryValue tempValue;
            SqlCommand command = connection.CreateCommand();

            command.CommandText = "GetDictionaryValue";
            command.CommandType = CommandType.StoredProcedure;

            command.Parameters.Add(new SqlParameter("@PropertyID", PropertyID));
            command.Parameters.Add(new SqlParameter("@LanguageID", LanguageID));

            if (connection.State == ConnectionState.Closed)
            {
                connection.Open();
            }

            reader = command.ExecuteReader();

            while (reader.Read())
            {
                tempValue = new DictionaryValue();
                tempValue.Name = (string)reader["Value"];
                tempValue.Value = (int)reader["IDdescription"];
                result.Add(tempValue);
            }

            reader.Close();

            connection.Close();

            return result;
        }

        /// <summary>
        /// Wybiera wszystkie właściwości dla określonej kategorii w wybranym języku.
        /// (Selects all properties for a defined category in a chosen language.)
        /// </summary>
        /// <param name="categoryID">
        /// Unikalne ID kategorii.
        /// (Unique category ID.)
        /// </param>
        /// <param name="LanguageID">
        /// Unikalne ID języka lub wartość 'NULL'.
        /// (Unique language ID or 'null' value.)
        /// </param>
        /// <returns>
        /// Zwraca listę obiektów ProductPropertyDetail zawierającą opisy właściwości produktu łącznie z możliwymi wartościami dla typów słownikowych.
        /// (Returns list of ProductPropertyDetail objects containing descriptions of product’s properties together with possible values for dictionaries types.)
        /// </returns>
        public List<ProductPropertyDetail> GetSearchCriteria(int categoryID, int? LanguageID)
        {
            SqlConnection connection = new SqlConnection(connectionString);
            ProductPropertyDetail tempProperty;
            List<ProductPropertyDetail> result = new List<ProductPropertyDetail>();
            SqlCommand command = connection.CreateCommand();
            SqlDataReader reader;

            command.CommandText = "GetSearchCriteria";
            command.CommandType = CommandType.StoredProcedure;
            command.Parameters.Add(new SqlParameter("@category_id", categoryID));
            command.Parameters.Add(new SqlParameter("@LanguageID", LanguageID));

            try
            {
                connection.Open();

                reader = command.ExecuteReader(CommandBehavior.CloseConnection);

                while (reader.Read())
                {
                    tempProperty = new ProductPropertyDetail();
                    tempProperty.Id = (int)reader["IDproperty"];
                    tempProperty.TypeOfProperty = (PropertyType)reader["PropertyType"];
                    tempProperty.Name = (string)reader["Name"];
                    tempProperty.IsSearchCriterion = (bool)reader["IsSearchCriterion"];

                    if (tempProperty.TypeOfProperty == PropertyType.Dictionary || tempProperty.TypeOfProperty == PropertyType.MultiDictionary)
                    {
                        tempProperty.ValuesList = GetDictionaryValue(tempProperty.Id, LanguageID);
                    }
                    result.Add(tempProperty);
                }

                reader.Close();

                return result;
            }
            catch (Exception ex)
            {
                ErrorLogger.LogError(ex);
                return null;
            }
            finally
            {
                connection.Close();
            }
        }

        /// <summary>
        /// Pobiera właściwości dala danej kategorii w określonym języku.
        /// (Downloads properties for given category in a defined language.)
        /// </summary>
        /// <param name="categoryID">
        /// Unikalne ID kategorii.
        /// (Unique category ID.)
        /// </param>
        /// <param name="LanguageID">
        /// Unikalne ID języka lub wartość 'NULL'.
        /// (Unique language ID or 'null' value.)
        /// </param>
        /// <returns>
        /// Zwraca listę obiektów ProductPropertyDetail zawierającą opisy właściwości produktu łącznie z możliwymi wartościami dla typów słownikowych.
        /// (Returns list of ProductPropertyDetail objects containing descriptions of product’s properties together with possible values for dictionaries types.)
        /// </returns>
        public List<ProductPropertyDetail> PropertyByCategory(int categoryID, int? LanguageID)
        {
            SqlConnection connection = new SqlConnection(connectionString);
            ProductPropertyDetail tempProperty;
            List<ProductPropertyDetail> result = new List<ProductPropertyDetail>();
            SqlCommand command = connection.CreateCommand();
            SqlDataReader reader;

            command.CommandText = "PropertyByCategory";
            command.CommandType = CommandType.StoredProcedure;

            command.Parameters.Add(new SqlParameter("@category_id", categoryID));
            command.Parameters.Add(new SqlParameter("@LanguageID", LanguageID));

            try
            {
                connection.Open();

                reader = command.ExecuteReader(CommandBehavior.CloseConnection);

                while (reader.Read())
                {
                    tempProperty = new ProductPropertyDetail();
                    tempProperty.Id = (int)reader["IDproperty"];
                    tempProperty.TypeOfProperty = (PropertyType)reader["PropertyType"];
                    tempProperty.Name = (string)reader["Name"];
                    tempProperty.IsSearchCriterion = (bool)reader["IsSearchCriterion"];

                    if (tempProperty.TypeOfProperty == PropertyType.Dictionary || tempProperty.TypeOfProperty == PropertyType.MultiDictionary)
                    {
                        tempProperty.ValuesList = GetDictionaryValue(tempProperty.Id, LanguageID);
                    }
                    result.Add(tempProperty);
                }

                reader.Close();

                return result;
            }
            catch (Exception ex)
            {
                ErrorLogger.LogError(ex);
                return null;
            }
            finally
            {
                connection.Close();
            }
        }

        /// <summary>
        /// Usuwa wartości z dziennika.
        /// (Deletes values from the dictionary.)
        /// </summary>
        /// <param name="ValuesToRemove">
        /// Lista obiektow int do usunięcia.
        /// (List of int objects to be deleted.)
        /// </param>
        /// <param name="cantRemove">
        /// Lista obiektow int, które nie mogły zostać usunięte.
        /// (List of int objects that couldn’t be deleted.)
        /// </param>
        /// <returns>
        /// Zwraca 'true' jeśli usuwanie z bazy powiodło się. 
        /// (Returns ‘true’ if removal succeeded.)
        /// </returns>
        public bool RemoveDictionaryValues(List<int> ValuesToRemove, out List<int> cantRemove)
        {
            cantRemove = new List<int>();

            if (ValuesToRemove != null && ValuesToRemove.Count > 0)
            {
                SqlConnection sqlC = new SqlConnection(connectionString);
                SqlCommand command = sqlC.CreateCommand();
                SqlTransaction transaction = null;

                command.CommandText = "RemoveDictionaryValue";
                command.CommandType = CommandType.StoredProcedure;

                command.Parameters.Add(new SqlParameter("@dictionary_id", SqlDbType.Int));

                try
                {
                    sqlC.Open();
                    transaction = sqlC.BeginTransaction();
                    command.Transaction = transaction;

                    for (int i = 0; i < ValuesToRemove.Count; i++)
                    {
                        command.Parameters["@dictionary_id"].Value = ValuesToRemove[i];

                        if (!Convert.ToBoolean(command.ExecuteScalar()))
                            cantRemove.Add(ValuesToRemove[i]);
                    }

                    transaction.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    ErrorLogger.LogError(ex);

                    if (sqlC.State == ConnectionState.Open && transaction != null)
                        transaction.Rollback();

                    return false;
                }
                finally
                {
                    sqlC.Close();
                }
            }

            return false;
        }

        /// <summary>
        /// Uaktualnia warosci dziennika.
        /// (Updates dictionary values.)
        /// </summary>
        /// <param name="newValueList">
        /// Lista obiektów DictionaryValue zawierająca opisy wartości słownika.
        /// (List of DictionaryValue objects containing descriptions of dictionary values.)
        /// </param>
        /// <param name="LanguageID">
        /// Unikalne ID języka lub wartość 'NULL'.
        /// (Unique language ID or 'null' value.)
        /// </param>
        /// <returns>
        /// Zwraca 'true' jeśli zmiany w bazie powiodły się. 
        /// (Returns ‘true’ if changes in the database succeeded.)
        /// </returns>
        public bool UpdateDictionaryValue(List<DictionaryValue> newValueList, int? LanguageID)
        {
            SqlConnection connection = new SqlConnection(connectionString);
            SqlCommand sqlCommand = connection.CreateCommand();

            sqlCommand.CommandText = "SaveDictionaryValue";
            sqlCommand.CommandType = CommandType.StoredProcedure;

            sqlCommand.Parameters.Add(new SqlParameter("@DictionaryID", null));
            sqlCommand.Parameters.Add(new SqlParameter("@Value", null));
            sqlCommand.Parameters.Add(new SqlParameter("@LanguageID", LanguageID));

            try
            {
                connection.Open();

                foreach (DictionaryValue current in newValueList)
                {
                    sqlCommand.Parameters["@DictionaryID"].Value = current.Value;
                    sqlCommand.Parameters["@Value"].Value = current.Name;

                    sqlCommand.ExecuteNonQuery();
                }
                return true;
            }
            catch (Exception ex)
            {
                ErrorLogger.LogError(ex);
                return false;
            }
            finally
            {
                connection.Close();
            }
        }

        /// <summary>
        /// Dodaje wartości do słownika.
        /// (Adds values to the dictionary.)
        /// </summary>
        /// <param name="values">
        /// Lista obiektów string zawierająca wartosci do dodania do słownika.
        /// (List of string objects containing values to be added to the dictionary.)
        /// </param>
        /// <param name="propertyId">
        /// Unikalne ID właściwości.
        /// (Unique property ID.)
        /// </param>
        /// <param name="LanguageID">
        /// Unikalne ID języka lub wartość 'NULL'.
        /// (Unique language ID or 'null' value.)
        /// </param>
        /// <returns>
        /// Zwraca 'true' jeśli dodawanie do bazy powiodło się. 
        /// (Returns ‘true’ if addition to the database succeeded.)
        /// </returns>
        public bool AddDictionaryValue(List<string> values, int propertyId, int? LanguageID)
        {
            int index = 0;
            SqlConnection connection = new SqlConnection(connectionString);
            SqlCommand sqlCommand = connection.CreateCommand();

            StringBuilder command = new StringBuilder();
            foreach (string current in values)
            {
                command.Append("EXEC SaveDictionaryValue NULL, ");
                command.Append(propertyId);
                command.Append(",@param");
                command.Append(index);
                command.Append(",");
                command.Append(LanguageID);
                command.Append(";");

                sqlCommand.Parameters.Add(new SqlParameter("@param" + index.ToString(), current));
                index++;
            }

            sqlCommand.CommandText = command.ToString();


            try
            {
                connection.Open();
                sqlCommand.ExecuteNonQuery();

                return true;
            }
            catch (Exception ex)
            {
                ErrorLogger.LogError(ex);
                return false;
            }
            finally
            {
                connection.Close();
            }
        }

        /// <summary>
        /// Zmienia informacje o wybranej właściwość w określonym języku.
        /// (Changes information about chosen value in a defined language.)
        /// </summary>
        /// <param name="item">
        /// Obiekt ProductPropertyDetail zawiarający informacje o właściwości.
        /// (ProductPropertyDetail object containing information about property.)
        /// </param>
        /// <param name="LanguageID">
        /// Unikalne ID języka lub wartość 'NULL'.
        /// (Unique language ID or 'null' value.)
        /// </param>
        /// <returns>
        /// Zwraca 'true' jeśli zmiany w bazie powiodły się. 
        /// (Returns ‘true’ if changes in tha database succeeded.)
        /// </returns>
        public bool UpdateProperty(ProductPropertyDetail item, int? LanguageID)
        {
            SqlConnection connection = new SqlConnection(connectionString);
            SqlCommand sqlCommand = connection.CreateCommand();

            sqlCommand.CommandText = "SaveProperty";
            sqlCommand.CommandType = CommandType.StoredProcedure;
            sqlCommand.Parameters.Add(new SqlParameter("@PropertyID", item.Id));
            sqlCommand.Parameters.Add(new SqlParameter("@Name", item.Name));
            sqlCommand.Parameters.Add(new SqlParameter("@Description", item.Description));
            sqlCommand.Parameters.Add(new SqlParameter("@LanguageID", LanguageID));
            sqlCommand.Parameters.Add(new SqlParameter("@PropertyType", (int)item.TypeOfProperty));
            sqlCommand.Parameters.Add(new SqlParameter("@IsSearchCriterion", item.IsSearchCriterion));

            try
            {
                connection.Open();
                sqlCommand.ExecuteNonQuery();

                return true;
            }
            catch (Exception ex)
            {
                ErrorLogger.LogError(ex);
                return false;
            }
            finally
            {
                connection.Close();
            }

        }

        /// <summary>
        /// Pobiera unikalne ID kategorii zawierających wybraną właściwość.
        /// (Downloads unique categories ID containing chosen property.)
        /// </summary>
        /// <param name="propertyId">
        /// Unikalne ID właściwości.
        /// (Unique property ID.)
        /// </param>
        /// <returns>
        /// Zwraca listę obiektow int z unikalnymi ID kategorii zawierających wybraną właściwość.
        /// (Returns list of int objects with unique categories ID containing chosen property.)
        /// </returns>
        public List<int> CategoryBelongProperty(int propertyId)
        {
            List<int> result = new List<int>();
            SqlConnection connection = new SqlConnection(connectionString);
            SqlCommand sqlCommand = connection.CreateCommand();
            SqlDataReader reader;

            sqlCommand.CommandText = "GetPropertyCategoryID";
            sqlCommand.CommandType = CommandType.StoredProcedure;

            sqlCommand.Parameters.Add(new SqlParameter("@property_id", propertyId));

            try
            {
                connection.Open();
                reader = sqlCommand.ExecuteReader(CommandBehavior.CloseConnection);

                while (reader.Read())
                {
                    result.Add((int)reader[0]);
                }

                reader.Close();
                return result;
            }
            catch (Exception ex)
            {
                ErrorLogger.LogError(ex);
                return null;
            }
            finally
            {
                connection.Close();
            }
        }

        /// <summary>
        /// Dodaje wybraną właściwość zd wskazanych kategorii.
        /// (Adds chosen property from selected categories.)
        /// </summary>
        /// <param name="propertyId">
        /// Unikalne ID właściwości.
        /// (Unique property ID.)
        /// </param>
        /// <param name="categoriesList">
        /// Lista obiektów int zawiarająca unikalne ID kategorii.
        /// (List of int objects containing unique category ID.)
        /// </param>
        /// <returns>
        /// Zwraca 'true' jeśli usuwanie z bazy powiodło się. 
        /// (Returns ‘true’ if removal from the database succeeded.)
        /// </returns>
        public bool AddPropertyToCategories(int propertyId, List<int> categoriesList)
        {
            if (categoriesList.Count == 0)
                return true;

            SqlConnection connection = new SqlConnection(connectionString);
            SqlCommand sqlCommand = connection.CreateCommand();

            sqlCommand.CommandText = "AddPropertyToCategories";
            sqlCommand.CommandType = CommandType.StoredProcedure;

            sqlCommand.Parameters.Add(new SqlParameter("@CategoryID", null));
            sqlCommand.Parameters.Add(new SqlParameter("@PropertyId", propertyId));

            try
            {
                connection.Open();

                foreach (int current in categoriesList)
                {
                    sqlCommand.Parameters["@CategoryID"].Value = current;

                    sqlCommand.ExecuteNonQuery();
                }

                return true;
            }
            catch (Exception ex)
            {
                ErrorLogger.LogError(ex);
                return false;
            }
            finally
            {
                connection.Close();
            }
        }

        /// <summary>
        /// Usuwa wybraną właściwość ze wskazanych kategorii.
        /// (Returns chosen property from the selected categories.)
        /// </()summary>
        /// <param name="propertyId">
        /// Unikalne ID właściwości.
        /// (Unique property ID.)
        /// </param>
        /// <param name="categoriesList">
        /// Lista obiektów int zawiarająca unikalne ID kategorii.
        /// (List of int objects containing unique categories ID.)
        /// </param>
        /// <returns>
        /// Zwraca 'true' jeśli usuwanie z bazy powiodło się. 
        /// (Returns ‘true’ if removal from the database succeeded.)
        /// </returns>
        public bool RemovePropertyFromCategories(int propertyId, List<int> categoriesList)
        {
            SqlConnection connection = new SqlConnection(connectionString);
            SqlCommand sqlCommand = connection.CreateCommand();

            sqlCommand.CommandText = "RemovePropertyFromCategories";
            sqlCommand.CommandType = CommandType.StoredProcedure;

            string categories = "";

            foreach (int current in categoriesList)
            {
                categories += current;
                categories += ",";
            }
            categories = categories.Remove(categories.Length - 1, 1);

            sqlCommand.Parameters.Add(new SqlParameter("@categoriesList", categories));
            sqlCommand.Parameters.Add(new SqlParameter("@propertyId", propertyId));

            try
            {
                connection.Open();

                sqlCommand.ExecuteNonQuery();
                return true;
            }
            catch (Exception ex)
            {
                ErrorLogger.LogError(ex);
                return false;
            }
            finally
            {
                connection.Close();
            }
        }

        /// <summary>
        /// Dodaje właściwość do bazy.
        /// (Adds property to the database.)
        /// </summary>
        /// <param name="property">
        /// Obiekt ProductPropertyDetail opisujący danaą właściwość.
        /// (ProductPropertyDetail object describing given property.)
        /// </param>
        /// <param name="LanguageID">
        /// Unikalne ID języka lub wartość 'NULL'.
        /// (Unique language ID or 'null' value.)
        /// </param>
        /// <returns>
        /// Zwraca unikalne ID wstawionej do bazy właściwości.
        /// (Returns unique ID of inserted to the database property.)
        /// </returns>
        public int AddProperty(ProductPropertyDetail property, int? LanguageID)
        {
            int id = 0;
            SqlConnection connection = new SqlConnection(connectionString);
            SqlCommand sqlCommand = connection.CreateCommand();

            sqlCommand.CommandText = "SaveProperty";
            sqlCommand.CommandType = CommandType.StoredProcedure;
            sqlCommand.Parameters.Add(new SqlParameter("@Name", property.Name));
            sqlCommand.Parameters.Add(new SqlParameter("@Description", property.Description));
            sqlCommand.Parameters.Add(new SqlParameter("@PropertyType", property.TypeOfProperty));
            sqlCommand.Parameters.Add(new SqlParameter("@LanguageID", LanguageID));
            sqlCommand.Parameters.Add(new SqlParameter("@IsSearchCriterion", property.IsSearchCriterion));

            try
            {
                connection.Open();

                id = Convert.ToInt32(sqlCommand.ExecuteScalar());

                if (property.ValuesList != null && property.ValuesList.Count > 0)
                {
                    List<string> newValues = new List<string>();
                    foreach (DictionaryValue current in property.ValuesList)
                    {
                        newValues.Add(current.Name);
                    }

                    AddDictionaryValue(newValues, id, LanguageID);
                }
                return id;
            }
            catch (Exception ex)
            {
                ErrorLogger.LogError(ex);
                return -1;
            }
            finally
            {
                connection.Close();
            }
        }

        /// <summary>
        /// Usuwa wybraną właściwośc z bazy.
        /// (Deletes selected property from the database.)
        /// </summary>
        /// <param name="propertyId">
        /// Unikalne ID właściwości.
        /// (Unique property ID.)
        /// </param>
        /// <returns>
        /// Zwraca wartość 'true' jeśli właściwość została prawidłowo usunięta z bazy.
        /// (Returns ‘true’ if property has been properly deleted from the database.)
        /// </returns>
        public bool RemoveProperty(int propertyId)
        {
            SqlConnection connection = new SqlConnection(connectionString);
            SqlCommand sqlCommand = connection.CreateCommand();

            sqlCommand.CommandText = "RemoveProperty";
            sqlCommand.CommandType = CommandType.StoredProcedure;

            sqlCommand.Parameters.Add(new SqlParameter("@propertyId", propertyId));

            try
            {
                connection.Open();
                sqlCommand.ExecuteNonQuery();
                return true;
            }
            catch (Exception ex)
            {
                ErrorLogger.LogError(ex);
                return false;
            }
            finally
            {
                connection.Close();
            }
        }

        /// <summary>
        /// Pobiera właściwości wybranego produktu w wybranym języku.
        /// (Downloads properties of selected products in a chosen language.)
        /// </summary>
        /// <param name="productId">
        /// Unikalne ID produktu.
        /// (Unique product ID.)
        /// </param>
        /// <param name="LanguageID">
        /// Unikalne ID języka lub wartość 'NULL'.
        /// (Unique language ID or 'null' value.)
        /// </param>
        /// <returns>
        /// Zwraca listę obiektów ProductProperty opisujących właściwości produktu.
        /// (Returns list of ProductProperty objects describing product’s properties.)
        /// </returns>
        public List<ProductProperty> GetProductProperty(int productId, int? LanguageID)
        {
            ProductProperty tempProperty;
            List<ProductProperty> result = new List<ProductProperty>();
            SqlDataReader reader;
            SqlConnection connection = new SqlConnection(connectionString);
            SqlCommand command = connection.CreateCommand();

            command.CommandText = "GetProductProperty";
            command.CommandType = CommandType.StoredProcedure;
            
            command.Parameters.Add(new SqlParameter("@product_id", productId));
            command.Parameters.Add(new SqlParameter("@LanguageID", LanguageID));

            try
            {
                connection.Open();

                reader = command.ExecuteReader(CommandBehavior.CloseConnection);

                while (reader.Read())
                {
                    tempProperty = new ProductProperty();
                    tempProperty.Id = (int)reader["IDproperty"];
                    tempProperty.TypeOfProperty = (PropertyType)reader["PropertyType"];
                    tempProperty.NumericValue = reader["NumericValue"] != DBNull.Value ? (decimal?)reader["NumericValue"] : null;
                    tempProperty.Name = reader["Name"].ToString();
                    tempProperty.Value = reader["Value"].ToString();
                    tempProperty.IsSearchCriterion = (bool)reader["IsSearchCriterion"];

                    result.Add(tempProperty);
                }


                reader.Close();

                return result;
            }
            catch (Exception ex)
            {
                ErrorLogger.LogError(ex);
                return new List<ProductProperty>();
            }
            finally
            {
                connection.Close();
            }
        }
    }
}
